﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OverStore.Configuration.Builder;
using OverStore.Configuration.Builder.Fluent;
using OverStore.Configuration.Components;
using System.Data.SqlClient;
using OverStore.Runtime.Storage;
using OverStore.Configuration.Storage;
using OverStore.Runtime.PersistenceServiceProvider;
using OverStore.Scoping;
using OverStore.Configuration;
using OverStore.Configuration.ObjectRepository.CommandSet;

namespace OverStore.TutorialAsTest.UnitTest
{
    [TestClass]
    public class ResourceCleanupTest
    {
        public class Master
        {
            public virtual long Id { get; set; }

            public virtual string Val1 { get; set; }
        }

        private static object GetMasterData(Master instance, string name, IRegistry registry)
        {
            var c = StringComparer.OrdinalIgnoreCase;
            if (c.Equals(name, "SUPERT_ID"))
                return instance.Id;
            if (c.Equals(name, "Val1"))
                return instance.Val1;
            throw new ArgumentException("Name is not supported.");
        }

        private static void ApplyMasterData(TypedRecord data, Master instance, IRegistry registry)
        {
            instance.Id = data.GetInt64("SUPERT_ID");
            instance.Val1 = data.GetString("Val1");
        }

        private static IPersistenceSessionFactory CreateConfig()
        {
            return OverStoreFluent.Configure()
                .LogToConsole()
                .ConnectToDatabase<SqlConnection>("User ID=sa;Password=sa1234;Initial Catalog=TestOrmDb;Data Source=.", ProcessOpenedReadersMode.ForciblyCloseReaders)
                .CustomClassRepository<Master, long>()
                    .WithDepot(Component.Depot.Delegate<Master, long>(
                                    () => new Master(),
                                    (instance, identifier) => instance.Id = identifier,
                                    Component.IdentifierGenerator.Delegate<Master, long>((instance, previous) => previous - 1, -1)))
                   .WithMapper(Component.Mapper.Delegate<Master>(GetMasterData, ApplyMasterData))
                   .CommandSet()
                        .SelectCommand()
                            .UseStoredProcedure("[dbo].[GET_ProcMasterDetails]")
                            .InputParameter("masterId", System.Data.DbType.Int64)
                        .EndCommand()
                        .AsReadOnly()
                    .EndCommandSet()
                   .ByIdentifierAttaching(i => i.Id)
                   .ParameterlessReader(true)
                    .WithCommand(new AdoNetCommandConfiguration
                    {
                        CommandType = System.Data.CommandType.StoredProcedure,
                        Sql = "[dbo].[GET_ProcMaster]",
                        ResultType = AdoCommandResultType.DataReaderResultSet
                    })
                    .WithIdentifierProvider(Component.IdentifierProvider.Delegate<long>(r => r.GetInt64("SUPERT_ID")))
                    .EndReader()
                .EndObjectRepository()
            .End();
        }

        private static readonly IPersistenceSessionFactory _Config = CreateConfig();

        public ICollection<Master> GetAllMaster()
        {
            using (var session = _Config.CreateSession())
            {
                using (var scope = session.OpenScope())
                {
                    return session.CreateReader<Master>().ToList();
                }
            }
        }

        [TestMethod]
        public void GetReaderManyTimes_SqlServer()
        {
            //Assert.Inconclusive("SQL Server is not installed");
            //for (int i = 0; i < 1000; i++)
            //{
            //    GetAllMaster();
            //}
        }
    }
}
